﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Batch_Disc_Backup
{
    /// <summary>
    /// Static class of some simple methods that don't really belong to their own class.
    /// </summary>
    public static class Quick
    {
        /// <summary>
        /// Checks the directory, and if it exists, place a " (2)" infront
        /// (or " (3)" etc, depending on what's next)
        /// </summary>
        /// <param name="dir"></param>
        /// <returns></returns>
        public static string NextDir(string dir)
        {
            string newDir = dir;
            int count = 1;
            while (Directory.Exists(newDir))
            {
                count++;
                newDir = dir + " (" + count + ")";
            }
            return newDir;
        }

        /// <summary>
        /// Checks the file in the directory, and if it exists, place a " (2)" infront
        /// (or " (3)" etc, depending on what's next)
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public static string NextFilename(string file)
        {
            string newFile = file;
            int count = 1;
            while (File.Exists(newFile))
            {
                count++;
                newFile = Path.Combine(Path.GetDirectoryName(file), Path.GetFileNameWithoutExtension(file) + " (" + count + ")" + Path.GetExtension(file));
            }
            return newFile;
        }

        /// <summary>
        /// String.Substring method, but handles if the indexOf is -1,
        /// then the full original string is returned rather than throwing an error.
        /// </summary>
        /// <param name="s"></param>
        /// <param name="indexOfS"></param>
        /// <returns></returns>
        public static string SubString(string s, string indexOfS)
        {
            int indexOf = s.IndexOf(indexOfS);
            if (indexOf == -1) return s;
            return s.Substring(0, indexOf);
        }

        /// <summary>
        /// Formats a byte amount to either KiB, MiB, GiB or TiB, depending on what's most relevant.
        /// </summary>
        /// <param name="length"></param>
        /// <param name="decimalsCount"></param>
        /// <returns></returns>
        public static String GetByteString(long length, int decimalsCount=2)
        {
            if (length < 1024) return length + " byte" + (length == 1 ? "" : "s");
            if (length < Math.Pow(1024, 2)) return FormatAndRound(length / 1024, decimalsCount) + "KiB";
            if (length < Math.Pow(1024, 3)) return FormatAndRound(length / Math.Pow(1024, 2), decimalsCount) + "MiB";
            if (length < Math.Pow(1024, 4)) return FormatAndRound(length / Math.Pow(1024, 3), decimalsCount) + "GiB";
            if (length < Math.Pow(1024, 5)) return FormatAndRound(length / Math.Pow(1024, 4), decimalsCount) + "TiB";

            return null;
        }

        /// <summary>
        /// Force round a double value to an amount of decimal spaces
        /// </summary>
        /// <param name="d"></param>
        /// <param name="decimalCount"></param>
        /// <returns></returns>
        public static String FormatAndRound(double d, int decimalCount=2)
        {
            StringBuilder sb = new StringBuilder("{0:0");
            if (decimalCount > 0) sb.Append(".");
            for (int i = 0; i < decimalCount; i++ ) sb.Append("0");
            sb.Append("}");
            return String.Format(sb.ToString(), d);
        }

        /// <summary>
        /// Returns a time with the two most relevant values.
        /// eg. "2d 3h" would be returned for a timespan of 2 days 3 hours 21mins 39 secs.
        /// </summary>
        /// <param name="timeSpan"></param>
        /// <returns></returns>
        public static string FriendlyTime(TimeSpan timeSpan)
        {
            if (timeSpan.Days > 0) return string.Format("{0}d {1}h", timeSpan.Days, timeSpan.Hours);
            else if (timeSpan.Hours > 0) return string.Format("{0}h {1}m", timeSpan.Hours, timeSpan.Minutes);
            else if (timeSpan.Minutes > 0) return string.Format("{0}m {1}s", timeSpan.Minutes, timeSpan.Seconds);
            else return string.Format("{0}s", timeSpan.Seconds);
        }
    }
}
